﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
using System.Xml.Serialization;
using UpdateClient.ICommandNotify;
using UpdateClient.Model;

namespace UpdateClient
{
    public class MainWindowViewModel
    {
        public MainWindowViewModel() 
        {
            DataModel = new MainWindowModel();
            VersionCommand = new Command(VersionCommand_);
            SelectPathCommand = new Command(SelectPathCommand_);
            historicalversionsCommand = new Command(historicalversionsCommand_);
            PublishUirCommand = new Command(PublishUirCommand_);
            ExistingPublishCommand = new Command(ExistingPublishCommand_);
            BaseDirectorypath = System.AppDomain.CurrentDomain.BaseDirectory;
            //初始化文件保存路径
            SourcePubliFile = Path.Combine(BaseDirectorypath, "SourcePubliFile");
            publishFileinfo = Path.Combine(BaseDirectorypath, "publishFileinfo");
            if (Directory.Exists(publishFileinfo))
            {
                DataModel.historicalversions = Directory.GetDirectories(publishFileinfo + "\\").Select(o=>new FileInfo(o)).OrderBy(o => o.CreationTime).ToList();               
                string number =(Convert.ToInt16 (DataModel.historicalversions.Last().Name.Replace(".", ""))+1).ToString();
                string part1 = number.Substring(0, 1);
                string part2 = number.Substring(1, 1);
                string part3 = number.Substring(2, 1);
                string part4 = number.Substring(3, 1);
                DataModel.VersionNumber = $"{part1}.{part2}.{part3}.{part4}";
                DataModel.Version = DataModel.historicalversions.Last().Name;
            }
            else
            {
                DataModel.VersionNumber = "1.0.0.0";
            }
            DataModel.PublishUir = ConfigurationManager.AppSettings["PublishUir"];
        }



        private readonly string BaseDirectorypath;
        private readonly string SourcePubliFile;
        private readonly string publishFileinfo;
        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="obj"></param>
        private  void PublishUirCommand_(object obj)
        {
            if (Directory.Exists($"{publishFileinfo}\\{DataModel.VersionNumber}")==false)
            {
                VersionCommand_(2);
                return;
            }
            if (Directory.GetFiles($"{publishFileinfo}\\{DataModel.VersionNumber}").Length == 0)
            {
                MessageBox.Show("没有可更新的文件", "提示");
                return;
            }
            Upload($"{publishFileinfo}\\{DataModel.VersionNumber}", Updateprogress("正在发布"));
            DataModel.ProgressBarDescribe = "发布完成";
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="filepath"></param>
        private async void Upload(string filepath, IProgress<int> progress)
        {
            string[] files = Directory.GetFiles(filepath, "*", SearchOption.AllDirectories);
            HttpClient httpClient = new HttpClient();
            int i = 0;
            foreach (var item in files)
            {
                try
                {
                    // 创建 MultipartFormDataContent 用于包含文件数据
                    var form = new MultipartFormDataContent();

                    // 读取文件内容并创建 ByteArrayContent
                    var fileContent = new ByteArrayContent(File.ReadAllBytes(item));

                    // 设置文件内容的 Content-Type（可根据需要设置）
                    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");

                    // 将文件添加到表单，字段名为 "file"
                     string itemfile= Path.GetFileName(item);
                    form.Add(fileContent, "file", itemfile);
                    // 将文件添加到表单，字段名为 "file"
                    form.Add(new StringContent(DataModel.VersionNumber), "Versioninfo");
                     // 发送 POST 请求上传文件
                     var response = await httpClient.PostAsync(DataModel.PublishUir, form);

                    // 读取并打印返回的结果
                    if (response.IsSuccessStatusCode)
                    {
                        i++;
                        progress?.Report((int)((float)i / files.Length * 100));  // 更新进度
                        DataModel.outputinfo = $"文件{itemfile}发布成功 \r";
                    }
                    else
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        DataModel.outputinfo = $"{item}发布失败 错误信息{responseContent}\r";
                    }
                }
                catch (Exception e)
                {
                    DataModel.outputinfo = $"{item}发布失败 错误信息{e.Message}\r";
                }
               
            }

        }
        private void ExistingPublishCommand_(object obj)
        {
            Upload(DataModel.FilePath, Updateprogress("正在上传文件..."));
            DataModel.ProgressBarDescribe = "发布完成";
        }
        /// <summary>
        /// 查看历史版本
        /// </summary>
        /// <param name="obj"></param>
        private void historicalversionsCommand_(object obj)
        {
           
            if (DataModel.historicalversions == null|| DataModel.historicalversions.Count==0)
            {
                MessageBox.Show("没有数据","提示");
                return;
            }
            VersionWindow versionWindow = new VersionWindow();
            versionWindow.DataContext = new VersionWindowViewModel(DataModel.historicalversions.OrderBy(t => t.LastWriteTime).Select(o => new FileModel()
            {
                Name = $"版本号:{o.Name}",
                modificationDate = $"发布时间:{o.LastWriteTimeUtc.ToString("yyyy/MM/dd HH:mm:ss")}",
                Size = $"更新文件数量:{Directory.GetFiles($"{publishFileinfo}\\{o.Name}").Length - 1}",
                Type = $"文件类型:文件夹"

            }).ToList(), publishFileinfo); 
   
            versionWindow.ShowDialog();
        }
        #region 方法
        /// <summary>
        /// 选择发布文件路径
        /// </summary>
        /// <param name="obj"></param>
        private void SelectPathCommand_(object obj)
        {
            // 创建 FolderBrowserDialog 实例
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            // 显示对话框
            DialogResult result = folderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                // 获取用户选择的文件夹路径
                DataModel.FilePath = folderBrowserDialog.SelectedPath;
                DataModel.FileList = null;
                DataModel.FileList = GetFilesRecursive(DataModel.FilePath);//获取文件
                //CopyFolder(DataModel.FilePath, System.AppDomain.CurrentDomain.BaseDirectory + "\\SourcePubliFile");
            }
        }
        /// <summary>
        /// 生成发布版本
        /// </summary>
        /// <param name="obj"></param>
        private async  void VersionCommand_(object obj)
        {         
            if (string.IsNullOrWhiteSpace(DataModel.FilePath))
            {
                MessageBox.Show("请选择文件路径","提示");
                return;
            }
            if (DataModel.SelectPubliType==0)
            {
                MessageBox.Show("请选择发布类型", "提示");
                return;
            }
            if (string.IsNullOrWhiteSpace(DataModel.VersionNumber))
            {
                MessageBox.Show("请输入版本号", "提示");
                return;
            }
            var VersionNumber_ = DataModel.VersionNumber.Split('.');
            if (VersionNumber_.Length ==4)
            {
                if(string.IsNullOrWhiteSpace(DataModel.Version)==false)
                {
                       var Version_ = DataModel.Version.Split('.');                  
                        if (Convert.ToInt16(DataModel.Version.Replace(".",""))>= Convert.ToInt16(DataModel.VersionNumber.Replace(".", "")))
                        {
                            MessageBox.Show("输入版本号格式不正确", "提示");
                            return;
                        }                 
                }
                else
                {
                    if (VersionNumber_[0] != "1")
                    {
                        MessageBox.Show("输入版本号格式不正确", "提示");
                        return;
                    }
                }              
            }
            else
            {
                MessageBox.Show("请输入版本格式不正确", "提示");
                return;
            }
            if (DataModel.historicalversions==null||DataModel.historicalversions.Count == 0)
            {              
                await  CoverageRelease();
                return;
            }
            if (DataModel.SelectPubliType == 1)//覆盖
            {
                await  CoverageRelease();
  
            }
            if (DataModel.SelectPubliType == 2)//比较生成
            {
                await  Compareandpublish();
                if (Directory.GetFiles($"{publishFileinfo}\\{DataModel.VersionNumber}").Length == 0)
                {
                    MessageBox.Show("没有可更新的文件", "提示");
                    DirectoryInfo directoryInfo = new DirectoryInfo($"{publishFileinfo}\\{DataModel.VersionNumber}");
                    directoryInfo.Delete(true);
                    Directory.Delete($"{SourcePubliFile}\\{DataModel.VersionNumber}", true);
                    return;
                }
            }
            if (obj?.ToString() == "2")
            {
                Upload($"{publishFileinfo}\\{DataModel.VersionNumber}", Updateprogress("正在发布"));
            }
        }
        /// <summary>
        /// 获取文件
        /// </summary>
        /// <param name="folderPath"></param>
        /// <param name="files"></param>
        private List<FileModel> GetFilesRecursive(string directoryPath)
        {
            List<FileModel> fileModels = new List<FileModel>();

            // 获取当前目录下的所有文件
            string[] files = Directory.GetFiles(directoryPath);
            foreach (var file in files)
            {
                FileInfo fileInfo = new FileInfo(file);

                var fileModel = new FileModel
                {
                    Name = fileInfo.Name,
                    modificationDate = fileInfo.LastWriteTime.ToString("yyyy/MM/dd HH:mm:ss"),
                    Type = fileInfo.Extension,
                    Size = fileInfo.Length.ToString(),
                    Children = new List<FileModel>() // 空的 Children，只有文件时没有子项
                };

                fileModels.Add(fileModel);
            }

            // 获取当前目录下的所有子目录，并递归获取它们的文件
            string[] subdirectories = Directory.GetDirectories(directoryPath);
            foreach (var subdirectory in subdirectories)
            {
                FileModel directoryModel = new FileModel
                {
                    Name = new DirectoryInfo(subdirectory).Name,
                    modificationDate = Directory.GetLastWriteTime(subdirectory).ToString("yyyy/MM/dd HH:mm:ss"),
                    Type = "文件夹", // 用字符串标明是目录
                    Size = string.Empty, // 目录不显示大小
                    Children = GetFilesRecursive(subdirectory) // 递归获取子目录的文件
                };

                fileModels.Add(directoryModel);
            }

            return fileModels;
        }
        /// <summary>
        /// 覆盖发布 紧生成
        /// </summary>
        private async Task CoverageRelease()
        {
            string currentPath = $"{publishFileinfo}\\{DataModel.VersionNumber}";
            if (Directory.Exists(currentPath) ==false)
            {
                Directory.CreateDirectory(currentPath);
            }
            await CompressFiles(DataModel.FilePath, currentPath, Updateprogress("正在压缩文件"));
            DataModel.ProgressBarDescribe = "生成完成";
            //Upload($"{UpdateFilepath}\\{DataModel.VersionNumber}");
        }
        /// <summary>
        /// 压缩文件
        /// </summary>
        /// <param name="files"></param>
        /// <param name="zipFilePath"></param>
        /// <param name="progress"></param>
        private async Task CompressFiles(string sourceDir, string outputDir, IProgress<int> progress)
        {
            await Task.Run(() =>
            {
                // 确保输出目录存在
                Directory.CreateDirectory(outputDir);

                // 获取所有文件（包括子目录文件）
                string[] files = Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories);
                FileInfo fileInfo = null;
                double i = 0;
                UpdateInfo UpdateInfo_ = new UpdateInfo();
                UpdateInfo_.PublishType = 1;
                foreach (var item in files)
                {
                    Uri baseUri = new Uri(DataModel.FilePath.TrimEnd('\\') + "\\", UriKind.Absolute);
                    Uri targetUri = new Uri(item, UriKind.Absolute);

               
                    fileInfo = new FileInfo(item);
                    UpdateInfoDtl updateInfo = new UpdateInfoDtl()
                    {
                        FilePath = Uri.UnescapeDataString(baseUri.MakeRelativeUri(targetUri).ToString())
                              .Replace('/', '\\'),
                        PackageName = Guid.NewGuid().ToString() + ".zip",
                        Type=1,
                        FileSize = fileInfo.Length
                    };
                    UpdateInfo_.Dtls.Add(updateInfo);


                    // 获取文件名（不含路径）
                    string fileName = Path.GetFileName(item);

                    // 生成 ZIP 文件路径
                    string zipPath = Path.Combine(outputDir, updateInfo.PackageName);

                    // 如果 ZIP 已存在，先删除
                    if (File.Exists(zipPath))
                    {
                        File.Delete(zipPath);
                    }
                    // 创建 ZIP 并添加文件
                    using (FileStream zipToCreate = new FileStream(zipPath, FileMode.Create))
                    {
                        using (ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create))
                        {
                            archive.CreateEntryFromFile(item, fileName, CompressionLevel.Optimal);
                        }
                    }
                    i++;
                    DataModel.ProgressBarValue = (int)(i / (double)files.Length * 100);

                }
                XmlSerializer serializer = new XmlSerializer(typeof(UpdateInfo));
                using (StringWriter writer = new StringWriter())
                {
                    serializer.Serialize(writer, UpdateInfo_);
                    string xmlOutput = writer.ToString();
                    File.WriteAllText($"{publishFileinfo}\\{DataModel.VersionNumber}\\update.xml", xmlOutput);
                }
                return Task.CompletedTask;
            });

        }
        // 异步压缩文件的方法
        private UpdateInfoDtl CompressFileAsync(string sourceDir, string outputDir,int type)
        {
                // 确保输出目录存在
                Directory.CreateDirectory(outputDir);

                // 获取所有文件（包括子目录文件）
                //string[] files = Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories);
                FileInfo fileInfo = null;
                UpdateInfoDtl UpdateInfo_ = new UpdateInfoDtl();
            //foreach (var item in files)
            //{
            //Uri baseUri = new Uri(DataModel.FilePath.TrimEnd('\\') + "\\", UriKind.Absolute);
            //Uri targetUri = new Uri(item, UriKind.Absolute);
                    Uri baseUri = new Uri(DataModel.FilePath.TrimEnd('\\') + "\\", UriKind.Absolute);
                    Uri targetUri = new Uri(sourceDir, UriKind.Absolute);
                    fileInfo = new FileInfo(sourceDir);

                     UpdateInfo_.FilePath = Uri.UnescapeDataString(baseUri.MakeRelativeUri(targetUri).ToString())
                   .Replace('/', '\\');
                   UpdateInfo_.PackageName = Guid.NewGuid().ToString() + ".zip";
                   UpdateInfo_.Type = type;
                   UpdateInfo_.FileSize = fileInfo.Length;



                    // 获取文件名（不含路径）
                    string fileName = Path.GetFileName(sourceDir);

                    // 生成 ZIP 文件路径
                    string zipPath = Path.Combine(outputDir, UpdateInfo_.PackageName);

                    // 如果 ZIP 已存在，先删除
                    if (File.Exists(zipPath))
                    {
                        File.Delete(zipPath);
                    }
                  try
                  {
                   // 创建 ZIP 并添加文件
                   using (FileStream zipToCreate = new FileStream(zipPath, FileMode.Create))
                  {
                    using (ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create))
                    {
                        archive.CreateEntryFromFile(sourceDir, fileName, CompressionLevel.Optimal);
                    }
                    }
                  //}
                   }
                   catch (Exception ex)
                   {
                   DataModel.outputinfo = $"压缩文件失败:{ex.Message}";
                  }
            return UpdateInfo_;


        }
        /// <summary>
        /// 解压
        /// </summary>
        /// <param name="zipFilePath"></param>
        /// <param name="destinationFolder"></param>
        private async Task ExtractZip(string zipFilePath, string destinationFolder, IProgress<int> progress)
        {
            // 检查 ZIP 文件是否存在
            if (!Directory.Exists(zipFilePath))
            {
                DataModel.ProgressBarDescribe = "解压失败,源文件不存在";
                return;
            }
            await Task.Run(() => 
            {
                // 如果目标文件夹不存在，则创建它
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }
                try
                {
                    string[] files = Directory.GetFiles(zipFilePath, "*.zip", SearchOption.AllDirectories);

                    int totalFiles = files.Length;
                    int filesExtracted = 0;
                   UpdateInfo person=xmlUpdateInfo(zipFilePath);
                    foreach (var item in files)
                    {
                        string name=  Path.GetFileName(item);
                        UpdateInfoDtl updateInfo = person.Dtls.FirstOrDefault(o => o.PackageName == name);
                        if(updateInfo!=null&&updateInfo.FilePath.Contains("\\"))
                        {
                            ZipFile.ExtractToDirectory(item, $"{destinationFolder}\\{Path.GetDirectoryName(updateInfo.FilePath)}");
                        }
                        else
                        {
                             ZipFile.ExtractToDirectory(item, destinationFolder);
                            
                           
                        }
                        // 更新进度
                        filesExtracted++;
                        int progressPercent = (int)((float)filesExtracted / totalFiles * 100);
                        progress?.Report(progressPercent);  // 更新进度
                    }  
                }
                catch (Exception ex)
                {
                    DataModel.outputinfo = $"解压失败 错误信息{ex.Message}\r";
                }
            });
        }
        private string GetRelativePath(string basePath, string fullPath)
        {
            Uri baseUri = new Uri(basePath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
            Uri fullUri = new Uri(fullPath);

            Uri relativeUri = baseUri.MakeRelativeUri(fullUri);
            return Uri.UnescapeDataString(relativeUri.ToString()).Replace('/', Path.DirectorySeparatorChar);
        }
        /// <summary>
        /// 比较更新
        /// </summary>
        /// <returns></returns>
        private async Task Compareandpublish()
        {
            string lastfilepath = $"{SourcePubliFile}\\1.0.0.0";
            string currentPath =  $"{publishFileinfo}\\{DataModel.Version}";
            if (Directory.Exists(lastfilepath) == false)
            {
                Directory.CreateDirectory(lastfilepath);
                await ExtractZip($"{publishFileinfo}\\1.0.0.0", lastfilepath, Updateprogress("正在解压上一个版本文件"));//解压上一个版本
            }
            //await CompressFiles(DataModel.FilePath, currentPath, Updateprogress("正在保存文件"));//压缩保存文件
        
            await  CompareAndCopyFiles(DataModel.FilePath, lastfilepath, $"{publishFileinfo}\\{DataModel.VersionNumber}", Updateprogress("正在比较是否有文件更新"));//比较文件
            if (xmlUpdateInfo($"{publishFileinfo}\\{DataModel.VersionNumber}").Dtls.Count == 0)
            {
                MessageBox.Show("没有更新的内容","提示");
                DataModel.ProgressBarValue = 100;
                DataModel.ProgressBarDescribe = "生成完成";//  
                return;
            }
            DataModel.ProgressBarValue = 100;
            DataModel.ProgressBarDescribe = "生成完成";//  
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <returns></returns>
        private UpdateInfo xmlUpdateInfo(string lastfilepath)
        {
            // 先读取 XML 文件内容
            string xmlContent = File.ReadAllText(lastfilepath + "\\update.xml");

            // 创建 XmlSerializer 对象
            XmlSerializer serializer = new XmlSerializer(typeof(UpdateInfo));
            UpdateInfo updateInfoList;
            using (StringReader reader = new StringReader(xmlContent))
            {
                // 进行反序列化
                updateInfoList = (UpdateInfo)serializer.Deserialize(reader);
            }
            return updateInfoList;
        }
        /// <summary>
        /// 更新进度条
        /// </summary>
        private IProgress<int> Updateprogress(string Content)
        {
            DataModel.ProgressBarDescribe = Content;
            var progress = new Progress<int>(percent =>
            {
                // 这里更新UI或者其他进度条
                DataModel.ProgressBarValue = percent;
            });
            return progress;
        }
        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="sourceFolder"></param>
        /// <param name="destinationFolder"></param>
        /// <exception cref="DirectoryNotFoundException"></exception>
        private void CopyFolder(string sourceFolder, string destinationFolder)
        {
            // 检查源文件夹是否存在
            if (!Directory.Exists(sourceFolder))
            {
                throw new DirectoryNotFoundException($"源文件夹 {sourceFolder} 不存在！");
            }

            // 如果目标文件夹不存在，则创建目标文件夹
            if (!Directory.Exists(destinationFolder))
            {
                Directory.CreateDirectory(destinationFolder);
            }

            // 复制源文件夹中的所有文件到目标文件夹
            foreach (string file in Directory.GetFiles(sourceFolder))
            {
                string destFile = Path.Combine(destinationFolder, Path.GetFileName(file));
                File.Copy(file, destFile, overwrite: true);
            }

            // 递归复制所有子文件夹
            foreach (string subfolder in Directory.GetDirectories(sourceFolder))
            {
                string destSubfolder = Path.Combine(destinationFolder, Path.GetFileName(subfolder));
                CopyFolder(subfolder, destSubfolder);  // 递归调用
            }
        }
        // 比较两个文件是否相同
        private  bool AreFilesDifferent(string file1, string file2)
        {
            // 如果文件不存在，则表示不同
            if (!File.Exists(file1) || !File.Exists(file2))
            {
                return true;
            }

            // 比较文件的哈希值
            string hash1 = GetFileHash(file1);
            string hash2 = GetFileHash(file2);

            return hash1 != hash2;
        }

        // 计算文件的哈希值
        private  string GetFileHash(string filePath)
        {
            using (var sha256 = SHA256.Create())
            {
                using (var stream = File.OpenRead(filePath))
                {
                    byte[] hashBytes = sha256.ComputeHash(stream);
                    return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
                }
            }
        }

        // 比较文件夹并复制更新的文件
        private  async Task CompareAndCopyFiles(string sourceFolder, string compareFolder, string destinationFolder,IProgress<int> progress)
        {
           await Task.Run(() => 
            {
                // 检查并创建目标文件夹
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }

                // 获取源文件夹中的所有文件
                string[] sourceFiles = Directory.GetFiles(sourceFolder, "*", SearchOption.AllDirectories);
                int filesExtracted = 0;
                int totalFiles = sourceFiles.Length;
                UpdateInfo UpdateInfo_ =new UpdateInfo();
                UpdateInfo_.PublishType = 2;
                foreach (var sourceFile in sourceFiles)
                {
                    // 获取文件相对路径
                    string relativePath = GetRelativePath(sourceFolder, sourceFile);
                    string compareFile = Path.Combine(compareFolder, relativePath);
                    // 检查比较文件夹是否包含这个文件
                    if (File.Exists(compareFile))
                    {
                        // 如果文件不同，复制到目标文件夹
                        if (AreFilesDifferent(sourceFile, compareFile))
                        {
                            UpdateInfoDtl updateInfo = CompressFileAsync(sourceFile, $"{publishFileinfo}//{DataModel.VersionNumber}", 2);
                            //updateInfo.FilePath = compareFile;
                            UpdateInfo_.Dtls.Add(updateInfo);
                        }
                    }
                    else
                    {
                        UpdateInfoDtl updateInfo= CompressFileAsync(sourceFile, $"{publishFileinfo}//{DataModel.VersionNumber}", 1);
                        UpdateInfo_.Dtls.Add(updateInfo);
                    }
                   
                    // 更新进度
                    filesExtracted++;
                    int progressPercent = (int)((float)filesExtracted / totalFiles * 100);
                    progress?.Report(progressPercent);  // 更新进度
                }
                XmlSerializer serializer = new XmlSerializer(typeof(UpdateInfo));
                using (StringWriter writer = new StringWriter())
                {
                    serializer.Serialize(writer, UpdateInfo_);
                    string xmlOutput = writer.ToString();
                    File.WriteAllText($"{publishFileinfo}\\{DataModel.VersionNumber}\\update.xml", xmlOutput);
                }
            });
           
        }
        #endregion
        #region 命令
        public ICommand VersionCommand { get; set; }
        public ICommand SelectPathCommand {  get; set; }
        public ICommand historicalversionsCommand {  get; set; }
        public ICommand PublishUirCommand {  get; set; }
        public ICommand ExistingPublishCommand {  get; set; }
        #endregion
        #region 属性
        public MainWindowModel DataModel { get; set; }
        #endregion

    }
}
